package com.rashith.metro.alfa;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rashith.metro.alfa.modles.WebPlace;
import com.rashith.metro.alfa.webservices.WebCall;

import ARKit.ARLayout;
import ARKit.MyPoint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class RashARActivity extends Activity implements OnClickListener,
		OnTouchListener {

	public static volatile Context ctx;
	ARLayout ar;
	volatile Location curLocation = null;
	private List<MyPoint> points;
	MyPoint pns;
	private static final String tag = "Rashith";
	public Bitmap image;
	public FrameLayout rl;
	public boolean froze = false;

	public int width, height;
	public Camera.ShutterCallback shutterCallBack;
	public Camera.PictureCallback raw, jpg;
	public String Catogory = "";
	private Preview myCamView;
	private Camera myCam;

	private LocationManager manager;
	private LocationListener listner;

	private float radious = 15f;
	private SharedPreferences pref;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		// if (getResources().getConfiguration().orientation ==
		// Configuration.ORIENTATION_PORTRAIT) {
		// //startActivity(new Intent(RashARActivity.this,
		// PlaceListActivity.class));
		// }

		// setContentView(R.layout.frame_layout);

		Catogory = getIntent().getExtras().get(ExploreActivity.CATAGORY)
				.toString();

		DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

		width = displaymetrics.widthPixels;
		height = displaymetrics.heightPixels;

		ctx = this.getApplicationContext();
		ar = new ARLayout(getApplicationContext(), height, width, 0.0f);
		ar.setOnTouchListener(RashARActivity.this);

		myCamView = new Preview(this);

		// WindowManager w = getWindowManager();
		// Display d = w.getDefaultDisplay();

		ar.screenHeight = height;
		ar.screenWidth = width;
		rl = new FrameLayout(ctx);

		rl.addView(myCamView);
		ar.debug = true;

		rl.addView(ar, width, height);

		LayoutInflater inflater = (LayoutInflater) this
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		RelativeLayout sideBar = (RelativeLayout) inflater.inflate(
				R.layout.arview, null);

		ImageButton direction = (ImageButton) sideBar
				.findViewById(R.id.imageButton1);

		direction.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				String def = "15";
				int index = -1;
				if (pref != null)
					def = pref.getString("distance", "15");

				final String[] value_arry = getResources().getStringArray(
						R.array.distance_values);

				for (int i = 0; i < value_arry.length; i++) {
					if (value_arry[i].equalsIgnoreCase(def))
						index = i;
				}

				AlertDialog.Builder builder = new AlertDialog.Builder(
						RashARActivity.this);
				builder.setTitle("Select a radious");
				DialogInterface.OnClickListener listner = new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {

						SharedPreferences.Editor editor = pref.edit();
						editor.putString("distance", value_arry[which]);
						editor.commit();
						radious = Float.parseFloat(value_arry[which]);
						new MyAsyncWebCall(RashARActivity.this, ar.curLocation
								.getLatitude(), ar.curLocation.getLongitude(),
								Catogory, radious).execute("");

						dialog.dismiss();

					}
				};
				builder.setSingleChoiceItems(R.array.distance, index, listner);

				AlertDialog dialog = builder.create();

				dialog.show();
			}
		});

		ImageButton search = (ImageButton) sideBar
				.findViewById(R.id.imageButton2);

		ImageButton list = (ImageButton) sideBar
				.findViewById(R.id.imageButtonList);
		list.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				if (netCheck()) {
					Intent i = new Intent(RashARActivity.this,
							PlaceListActivity.class);
					i.putExtra(PlaceListActivity.CATEGORY, Catogory);
					startActivity(i);
				}
			}
		});

		rl.addView(sideBar, 100, height);
		setContentView(rl);

		Location location = new Location("Test");
		location.setLatitude(6.912714);
		location.setLongitude(79.850786);
		location.setAltitude(12);

		// SLIIT
		// location.setLatitude(6.91373);
		// location.setLongitude(79.97632);

		ar.curLocation = location;

		pref = PreferenceManager
				.getDefaultSharedPreferences(RashARActivity.this);
		radious = Float.parseFloat(pref.getString("distance", "15"));

		// checkOriaantation();

		new MyAsyncWebCall(RashARActivity.this, ar.curLocation.getLatitude(),
				ar.curLocation.getLongitude(), Catogory, radious).execute("");

		rePoplulate(location);
		// Toast.makeText(this, "Plaese Wiat till GPS",
		// Toast.LENGTH_LONG).show();

		manager = (LocationManager) this
				.getSystemService(Context.LOCATION_SERVICE);
		listner = new LocationListener() {

			@Override
			public void onStatusChanged(String provider, int status,
					Bundle extras) {

			}

			@Override
			public void onProviderEnabled(String provider) {

			}

			@Override
			public void onProviderDisabled(String provider) {

			}

			@Override
			public void onLocationChanged(Location location) {

				ar.GPSLocked = true;
				curLocation = location;
				ar.curLocation = location;
				rePoplulate(location);

			}

		};

		manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1,
				listner);

		// -----------------------------Cam Listenrs
		// ////////
		shutterCallBack = new ShutterCallback() {

			@Override
			public void onShutter() {
				// TODO Auto-generated method stub

			}
		};

		raw = new PictureCallback() {

			@Override
			public void onPictureTaken(byte[] data, Camera camera) {

			}
		};

		jpg = new PictureCallback() {

			@Override
			public void onPictureTaken(byte[] data, Camera camera) {
				// TODO Auto-generated method stub
				try {

					// Intent i = new Intent(RashARActivity.this,
					// TestActivity.class);
					// i.putExtra("image", data);
					// startActivity(i);

					Bitmap bb = BitmapFactory.decodeByteArray(data, 0,
							data.length);
					ImageView iv = new ImageView(RashARActivity.this);
					iv.setImageBitmap(bb);

					rl.addView(iv);

				} catch (Exception e) {
					Log.e(tag, e.getMessage());
				}
			}
		};

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.cat_menu, menu);
		return true;
	}

	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub
		super.onBackPressed();
		Intent intent = new Intent(RashARActivity.this, ExploreActivity.class);
		startActivity(intent);
	}

	private boolean netCheck() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = cm.getActiveNetworkInfo();
		if (netInfo != null && netInfo.isConnected()) {
			return true;
		}
		Toast.makeText(getApplicationContext(),
				"Internet connectivity is required.", Toast.LENGTH_LONG).show();
		return false;
	}

	/**
	 * <p>
	 * check the device orientation
	 * </p>
	 * 
	 * @return void
	 * @author Rashith M Jayasekara
	 * 
	 */
	private boolean checkOriaantation() {
		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
			Intent i = new Intent(RashARActivity.this, PlaceListActivity.class);
			i.putExtra(PlaceListActivity.CATEGORY, Catogory);
			startActivity(i);
			return true;

		}
		return false;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {

		switch (item.getItemId()) {
		case R.id.Settings:
			startActivity(new Intent(RashARActivity.this, AppPref.class));
		}
		return true;
	}

	public void setPointList(List<MyPoint> l) {
		points = l;
		rePoplulate(ar.curLocation);
	}

	public void rePoplulate(Location location) {
		if (ar != null) {
			ar.clearARViews();

//			Location pLoc = new Location("pns");
//			pLoc.setLatitude(6.914836);
//			pLoc.setLongitude(79.971955);
//			// pLoc.setAltitude(0);
//			pns = new MyPoint(ctx, location, pLoc, "Perera & Sons", "food",
//					"00011");
//			pns.setID("00011");
//			pns.setPhone("0776615380");
//			pns.setAddress("No 24\nMalabe Road, Valivita");
//
//			pns.distance = 200;
//			ar.addARView(pns);
//
//			Location pizza = new Location("Pizza");
//			pizza.setLatitude(6.904045);
//			pizza.setLongitude(79.955736);
//			pizza.setAltitude(0);
//			MyPoint piz = new MyPoint(ctx, location, pizza, "pizza", "food",
//					"00010");
//			piz.distance = 5000;
//			ar.addARView(piz);

			if (points != null && points.size() > 0) {
				for (MyPoint p : points)
					ar.addARView(p);
			}

			/*
			 * Location pLoc = new Location("pns"); pLoc.setLatitude(6.91493);
			 * pLoc.setLongitude(79.97195); //pLoc.setAltitude(0); MyPoint pns =
			 * new MyPoint(ctx, location, pLoc, "pns"); pns.distance = 20;
			 * ar.addARView(pns);
			 * 
			 * Location pizza = new Location("Pizza");
			 * pizza.setLatitude(6.904045); pizza.setLongitude(79.955736);
			 * //pizza.setAltitude(0); MyPoint piz = new MyPoint(ctx, location,
			 * pizza, "pizza"); piz.distance = 20; ar.addARView(piz);
			 * 
			 * Location sapu = new Location("sapu"); sapu.setLatitude(6.96284);
			 * sapu.setLongitude(79.95708); //sapu.setAltitude(0); MyPoint
			 * sapugas = new MyPoint(ctx, location, sapu, "sapu");
			 * sapugas.distance = 20; ar.addARView(sapugas);
			 * 
			 * Location pizza2 = new Location("Pizza");
			 * pizza2.setLatitude(6.97488); pizza2.setLongitude(79.92282);
			 * 
			 * //pizza2.setAltitude(0); MyPoint piz2 = new MyPoint(ctx,
			 * location, pizza2, "pizza"); piz2.distance = 20;
			 * ar.addARView(piz2);
			 * 
			 * 
			 * //hard coded MyPoint ll = new MyPoint(ctx, null, null, "pns");
			 * ll.azimuth = 190.0f; ll.distance = 20; ll.inclination = -10;
			 * ar.addARView(ll);
			 * 
			 * MyPoint l2 = new MyPoint(ctx, null, null, "pizza"); l2.azimuth =
			 * 112.0f; l2.distance = 35; ar.addARView(l2);
			 * 
			 * MyPoint sapugas2 = new MyPoint(ctx, location, sapu, "sapu");
			 * sapugas2.azimuth = 249; sapugas2.distance = 2000;
			 * ar.addARView(sapugas2);
			 */

			ar.postInvalidate();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		manager.removeUpdates(listner);
		// if (myCam != null) {
		// myCamView.setCamera(null);
		// myCam.release();
		// myCam = null;
		// }

	}

	@Override
	protected void onDestroy() {
		if (myCam != null) {
			myCamView.setCamera(null);
			myCam.release();
			myCam = null;
		}
		ar.close();
		super.onDestroy();

	}

	@Override
	protected void onResume() {
		super.onResume();
		if (myCam == null) {
			myCam = Camera.open(0);
			myCamView.setCamera(myCam);
		}
		if (froze)
			myCam.startPreview();
		ar.GPSLocked = false;
		manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1,
				listner);
		Toast.makeText(this, "Plaese Wiat till GPS", Toast.LENGTH_LONG).show();

		radious = Float.parseFloat(pref.getString("distance", "15"));
		rePoplulate(ar.curLocation);
		// new MyAsyncWebCall(RashARActivity.this, ar.curLocation.getLatitude(),
		// ar.curLocation.getLongitude(), Catogory, radious).execute("");
	}

	// Googles Camera Code

	class Preview extends ViewGroup implements SurfaceHolder.Callback {
		private final String TAG = "Preview";

		SurfaceView mSurfaceView;
		SurfaceHolder mHolder;
		Size mPreviewSize;
		List<Size> mSupportedPreviewSizes;
		Camera mCamera;

		Preview(Context context) {
			super(context);

			mSurfaceView = new SurfaceView(context);
			addView(mSurfaceView);

			// Install a SurfaceHolder.Callback so we get notified when the
			// underlying surface is created and destroyed.
			mHolder = mSurfaceView.getHolder();
			mHolder.addCallback(this);
			// mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}

		public void setCamera(Camera camera) {
			mCamera = camera;
			if (mCamera != null) {
				mSupportedPreviewSizes = mCamera.getParameters()
						.getSupportedPreviewSizes();
				requestLayout();
			}
		}

		public void switchCamera(Camera camera) {
			setCamera(camera);
			try {
				camera.setPreviewDisplay(mHolder);
			} catch (IOException exception) {
				Log.e(TAG, "IOException caused by setPreviewDisplay()",
						exception);
			}
			Camera.Parameters parameters = camera.getParameters();
			parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
			requestLayout();

			camera.setParameters(parameters);
		}

		@Override
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			// We purposely disregard child measurements because act as a
			// wrapper to a SurfaceView that centers the camera preview instead
			// of stretching it.
			final int width = resolveSize(getSuggestedMinimumWidth(),
					widthMeasureSpec);
			final int height = resolveSize(getSuggestedMinimumHeight(),
					heightMeasureSpec);
			setMeasuredDimension(width, height);

			if (mSupportedPreviewSizes != null) {
				mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes,
						width, height);
			}
		}

		@Override
		protected void onLayout(boolean changed, int l, int t, int r, int b) {
			if (changed && getChildCount() > 0) {
				final View child = getChildAt(0);

				final int width = r - l;
				final int height = b - t;

				int previewWidth = width;
				int previewHeight = height;
				if (mPreviewSize != null) {
					previewWidth = mPreviewSize.width;
					previewHeight = mPreviewSize.height;
				}

				// Center the child SurfaceView within the parent.
				if (width * previewHeight > height * previewWidth) {
					final int scaledChildWidth = previewWidth * height
							/ previewHeight;
					child.layout((width - scaledChildWidth) / 2, 0,
							(width + scaledChildWidth) / 2, height);
				} else {
					final int scaledChildHeight = previewHeight * width
							/ previewWidth;
					child.layout(0, (height - scaledChildHeight) / 2, width,
							(height + scaledChildHeight) / 2);
				}
			}
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// The Surface has been created, acquire the camera and tell it
			// where
			// to draw.
			try {
				if (mCamera != null) {
					Camera.Parameters parameters = mCamera.getParameters();
					parameters.set("jpeg-quality", 100);
					parameters.setPictureFormat(ImageFormat.JPEG);
					parameters.setPictureSize(width, height);
					mCamera.setParameters(parameters);
					mCamera.setPreviewDisplay(holder);
				}
			} catch (IOException exception) {
				Log.e(TAG, "IOException caused by setPreviewDisplay()",
						exception);
			}
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// Surface will be destroyed when we return, so stop the preview.
			if (mCamera != null) {
				mCamera.stopPreview();
			}
		}

		private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
			final double ASPECT_TOLERANCE = 0.1;
			double targetRatio = (double) w / h;
			if (sizes == null)
				return null;

			Size optimalSize = null;
			double minDiff = Double.MAX_VALUE;

			int targetHeight = h;

			// Try to find an size match aspect ratio and size
			for (Size size : sizes) {
				double ratio = (double) size.width / size.height;
				if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
					continue;
				if (Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = Math.abs(size.height - targetHeight);
				}
			}

			// Cannot find the one match the aspect ratio, ignore the
			// requirement
			if (optimalSize == null) {
				minDiff = Double.MAX_VALUE;
				for (Size size : sizes) {
					if (Math.abs(size.height - targetHeight) < minDiff) {
						optimalSize = size;
						minDiff = Math.abs(size.height - targetHeight);
					}
				}
			}
			return optimalSize;
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int w,
				int h) {
			// Now that the size is known, set up the camera parameters and
			// begin
			// the preview.
			Camera.Parameters parameters = mCamera.getParameters();
			parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
			requestLayout();

			mCamera.setParameters(parameters);
			mCamera.startPreview();
		}

	}

	// Loading places from webservice

	class MyAsyncWebCall extends AsyncTask<String, Integer, List<MyPoint>> {

		Context context;
		private double lat;

		ProgressDialog pDialog;
		private String cat;
		private double lon;
		private float rad;

		public MyAsyncWebCall(Context c, double latlatitude, double longitude,
				String _Category, float radiuos) {
			context = c;
			lat = latlatitude;
			lon = longitude;
			cat = _Category;
			rad = radiuos;
			pDialog = new ProgressDialog(context);
			pDialog.setMessage("Loading Places...");
			pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			pDialog.setCancelable(false);
		}

		@Override
		protected void onPreExecute() {
			pDialog.setMessage("Loading Places...");
			pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			pDialog.show();
		}

		@Override
		protected List<MyPoint> doInBackground(String... params) {

			String response = WebCall.getPlaces(lat, lon, cat, rad);
			if (response == null)
				return null;
			String s = response.replace("</string>", "");
			s = s.replace("<string xmlns=\"http://www.metro360.com/\">", "");
			s = s.replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");

			Gson parser = new Gson();

			Type myType = new TypeToken<List<WebPlace>>() {
			}.getType();
			List<WebPlace> list = parser.fromJson(s, myType);

			List<MyPoint> result = null;
			if (list != null && list.size() > 0) {
				result = new ArrayList<MyPoint>();

				for (int i = 0; i < list.size(); i++) {

					WebPlace place = list.get(i);
					if (place != null) {
						Location pLoc = new Location(place.getName());
						pLoc.setLatitude(Double.parseDouble(place.getLatitude()));
						pLoc.setLongitude(Double.parseDouble(place
								.getLongitude()));
						pLoc.setAltitude(Double.parseDouble(place.getAltitude()));
						MyPoint p = new MyPoint(RashARActivity.this,
								ar.curLocation, pLoc, place.getName(), place
										.getCatogory().toLowerCase(),
								place.getID());

						// p.setOnTouchListener(RashARActivity.this);
						// p.setOnClickListener(RashARActivity.this);
						p.setUrl(place.getLogo());
						p.setID(place.getID());
						p.setAddress(place.getAddress());
						p.setPhone(place.getPhone());
						result.add(p);
					}
				}
			}

			return result;
		}

		@Override
		protected void onPostExecute(List<MyPoint> result) {
			pDialog.dismiss();
			setPointList(result);
		}

	}

	@Override
	public void onClick(View v) {
		Toast.makeText(RashARActivity.this, "Hellooo", Toast.LENGTH_LONG)
				.show();

		for (MyPoint f : points) {
			int[] cc = new int[] { -1, -1 };
			f.getLocationOnScreen(cc);
			int c = cc[0];
			int y = 0;
		}

		try {
			MyPoint p = (MyPoint) v;
			Toast.makeText(RashARActivity.this, p.get_name(), Toast.LENGTH_LONG)
					.show();
		} catch (Exception e) {

		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {

		float touch_x = event.getX();
		float touch_y = event.getY();

		float left, top, bottom, rigth;

//		if (touch_x >= left && touch_x <= rigth && touch_y >= top
//				&& touch_y <= bottom) {
//
//			if (myCam != null && !froze) {
//				myCam.stopPreview();
//				froze = true;
//				// myCam.takePicture(shutterCallBack, raw, jpg);
//			} else {
//				myCam.startPreview();
//				froze = false;
//			}
//			ar.removeARView(pns);
//			Intent x = new Intent(RashARActivity.this, PopUpActivity.class);
//			x.putExtra("ID", "00011");
//			x.putExtra("tel", "+94 11 4411376");
//			x.putExtra("name", "Perera & Sons");
//
//			startActivity(x);
//		}

		if (points != null ) {
			for (MyPoint f : points) {

				left = f.getLeft();
				rigth = left + 100;
				top = f.getTop();
				bottom = top + 100;

				if (touch_x >= left && touch_x <= rigth && touch_y >= top
						&& touch_y <= bottom) {
					Toast.makeText(RashARActivity.this, f.get_name(),
							Toast.LENGTH_LONG).show();

					String url = f.getUrl();
					url = "http://192.168.1.50:9001/Service.asmx/LocationItems?LID="
							+ f.getID();
					Intent i = new Intent(RashARActivity.this,
							WebViewActivity.class);
					i.putExtra(WebViewActivity.WEB_URL, url);
					
					
					if (myCam != null && !froze) {
						myCam.stopPreview();
						froze = true;
						// myCam.takePicture(shutterCallBack, raw, jpg);
					} else {
						myCam.startPreview();
						froze = false;
					}

					
					Intent x = new Intent(RashARActivity.this,
							PopUpActivity.class);

					x.putExtra("ID", f.getID());
					x.putExtra("tel", f.getPhone());
					x.putExtra("name", f.get_name());
					startActivity(x);
					ar.clearARViews();
					
					break;
				}

			}
		}
		return false;
	}

}